// import com.alibaba.druid.DbType;
// import com.alibaba.druid.sql.ast.*;
// import com.alibaba.druid.sql.ast.expr.*;
// import com.alibaba.druid.sql.ast.expr.SQLCaseExpr.Item;
// import com.alibaba.druid.sql.ast.statement.*;
// import com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause;
// import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOrderingExpr;
// import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr;
// import com.alibaba.druid.sql.dialect.mysql.ast.statement.*;
// import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
// import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExecuteImmediateStatement;
// import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement;
// import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement;
// import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement;
// import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement;
// import com.alibaba.druid.sql.parser.SQLStatementParser;
// import com.alibaba.druid.sql.visitor.ExportParameterVisitor;
// import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
// import com.alibaba.druid.sql.visitor.SQLEvalVisitorUtils;
// import com.alibaba.druid.sql.visitor.functions.Nil;
// import com.alibaba.druid.support.logging.Log;
// import com.alibaba.druid.support.logging.LogFactory;
// import com.alibaba.druid.util.FnvHash;
// import com.alibaba.druid.util.JdbcUtils;
// import com.alibaba.druid.util.ServletPathMatcher;
// import com.alibaba.druid.util.StringUtils;
// import com.alibaba.druid.wall.*;
// import com.alibaba.druid.wall.WallConfig.TenantCallBack;
// import com.alibaba.druid.wall.WallConfig.TenantCallBack.StatementType;
// import com.alibaba.druid.wall.violation.ErrorCode;
// import com.alibaba.druid.wall.violation.IllegalSQLObjectViolation;

// import java.io.BufferedReader;
// import java.io.IOException;
// import java.io.InputStream;
// import java.io.InputStreamReader;
// import java.net.URL;
// import java.util.*;

// import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_VALUE;
#pragma once
#include <thread>
#include "../../utils/common_ptr.h"

     class WallVisitorUtils_WallTopStatementContext {
        public:
    //     bool fromSysTable;
    //     bool fromSysSchema;

    //     bool fromPermitTable;

    //     bool fromSysTable() ;

    //     void setFromSysTable(bool fromSysTable) ;

    //     bool fromSysSchema() ;

    //     void setFromSysSchema(bool fromSysSchema) ;

    //     bool fromPermitTable() ;

    //     void setFromPermitTable(bool fromPermitTable) ;
    };

     class WallVisitorUtils_WallConditionContext {
        public:
        bool partAlwayTrue;
        bool partAlwayFalse;
        bool constArithmetic;
        bool xor_;
        bool bitwise;

        bool hasPartAlwayTrue() ;

        void setPartAlwayTrue(bool partAllowTrue) ;

        bool hasPartAlwayFalse() ;

        void setPartAlwayFalse(bool partAlwayFalse);

        bool hasConstArithmetic() ;

        void setConstArithmetic(bool constArithmetic) ;

        bool hasXor() ;

        void setXor(bool xor_) ;

        bool hasBitwise() ;

        void setBitwise(bool bitwise) ;

    };

class WallVisitorUtils {
public:
    // static Log LOG = LogFactory.getLog(WallVisitorUtils.class);

    static std::string HAS_TRUE_LIKE ;

    // static String[] whiteHints = {"LOCAL", "TEMPORARY", "SQL_NO_CACHE", "SQL_CACHE", "HIGH_PRIORITY",
    //         "LOW_PRIORITY", "STRAIGHT_JOIN", "SQL_BUFFER_RESULT", "SQL_BIG_RESULT", "SQL_SMALL_RESULT", "DELAYED"};

    // static void check(WallVisitor_ptr visitor, SQLInListExpr x) ;

    // static bool check(WallVisitor_ptr visitor, SQLBinaryOpExpr x) ;

    // static bool check(WallVisitor_ptr visitor, SQLBinaryOpExprGroup x) ;

    // static void check(WallVisitor_ptr visitor, SQLCreateTableStatement x) ;

    // static void check(WallVisitor_ptr visitor, SQLAlterTableStatement x) ;

    // static void check(WallVisitor_ptr visitor, SQLDropTableStatement x) ;

    // static void check(WallVisitor_ptr visitor, SQLSelectItem x) ;

    // static void check(WallVisitor_ptr visitor, SQLPropertyExpr x) ;

    // static void checkInsert(WallVisitor_ptr visitor, SQLInsertInto x) ;

    // static void checkSelelct(WallVisitor_ptr visitor, SQLSelectQueryBlock x) ;

    // static void checkHaving(WallVisitor_ptr visitor, SQLExpr x) ;

    // static void checkDelete(WallVisitor_ptr visitor, SQLDeleteStatement x) ;

    // static bool isSimpleConstExpr(SQLExpr sqlExpr) ;

    // static void checkCondition(WallVisitor_ptr visitor, SQLExpr x) ;

    // static void checkJoinSelectForMultiTenant(WallVisitor_ptr visitor, SQLJoinTableSource join,
    //                                                   SQLSelectQueryBlock x) ;

    // static bool isSelectStatmentForMultiTenant(SQLSelectQueryBlock queryBlock) ;

    // static void checkSelectForMultiTenant(WallVisitor_ptr visitor, SQLSelectQueryBlock x) ;

    // static void checkUpdateForMultiTenant(WallVisitor_ptr visitor, SQLUpdateStatement x) ;

    // static void checkInsertForMultiTenant(WallVisitor_ptr visitor, SQLInsertInto x) ;

    // static List<SQLSelectQueryBlock> splitSQLSelectQuery(SQLSelectQuery x) ;

    // // @Deprecated
    // static void checkConditionForMultiTenant(WallVisitor_ptr visitor, SQLExpr x, SQLObject_ptr parent) ;

    // // @Deprecated
    // static void checkJoinConditionForMultiTenant(WallVisitor_ptr visitor, SQLJoinTableSource join,
    //                                                     bool checkLeft, StatementType statementType) ;

    // // @Deprecated
    // static SQLBinaryOpExpr createTenantCondition(WallVisitor_ptr visitor, String alias,
    //                                                      StatementType statementType, String tableName) ;

    // static SQLExpr generateTenantValue(WallVisitor_ptr visitor, String alias, StatementType statementType,
    //                                            String tableName) ;

    // static void checkReadOnly(WallVisitor_ptr visitor, SQLTableSource tableSource) ;

    // static void checkUpdate(WallVisitor_ptr visitor, SQLUpdateStatement x) ;

    // static Object_ptr getValue(WallVisitor_ptr visitor, SQLBinaryOpExprGroup x) ;

    // static Object_ptr getValue(WallVisitor_ptr visitor, SQLBinaryOpExpr x) ;

    // static Object_ptr getValue_or(WallVisitor_ptr visitor, List<SQLExpr> groupList) ;

    // static Object_ptr getValue_and(WallVisitor_ptr visitor, List<SQLExpr> groupList) ;

    // static SQLExpr getFirst(SQLExpr x) ;

    // static List<SQLExpr> getParts(SQLExpr x) ;

    // static List<SQLExpr> partExpr(List<SQLExpr> exprs) ;

    // static bool isFirst(SQLObject_ptr x) ;

    // static bool hasWhere(SQLSelectQuery selectQuery) ;

    // static bool checkSqlExpr(SQLExpr x) ;

    // static bool isWhereOrHaving(SQLObject_ptr x) ;

    static thread_local WallVisitorUtils_WallConditionContext_ptr wallConditionContextLocal  ;
    // static ThreadLocal<WallTopStatementContext> wallTopStatementContextLocal = new ThreadLocal<WallTopStatementContext>();

    static WallVisitorUtils_WallConditionContext_ptr getWallConditionContext() ;

    // static WallTopStatementContext getWallTopStatementContext() ;

    // static void clearWallTopStatementContext() ;

    // static void initWallTopStatementContext() ;

    // static Object_ptr getConditionValue(WallVisitor_ptr visitor, SQLExpr x, bool alwayTrueCheck) ;

    static Object_ptr getValueFromAttributes(WallVisitor_ptr visitor, SQLObject_ptr sqlObject) ;

    static Object_ptr getValue(SQLExpr_ptr x) ;

    static Object_ptr getValue(WallVisitor_ptr visitor, SQLExpr_ptr x) ;

    static Object_ptr eval(WallVisitor_ptr wallVisitor, DbType_ptr dbType, SQLObject_ptr sqlObject, Object_list_ptr parameters) ;

    // static bool isSimpleCountTableSource(WallVisitor_ptr visitor, SQLTableSource tableSource) ;

    static bool isSimpleCountTableSource(WallVisitor_ptr visitor, SQLSelect_ptr select) ;

    static bool isSimpleCaseTableSource(WallVisitor_ptr visitor, SQLSelect_ptr select) ;

    // static void checkFunctionInTableSource(WallVisitor_ptr visitor, SQLMethodInvokeExpr x) ;

    // static void checkFunction(WallVisitor_ptr visitor, SQLMethodInvokeExpr x) ;

    // static SQLSelectQueryBlock getQueryBlock(SQLObject_ptr x) ;

    // static bool isTopNoneFromSelect(WallVisitor_ptr visitor, SQLObject_ptr x) ;

    // static bool isTopFromDenySchema(WallVisitor_ptr visitor, SQLMethodInvokeExpr x) ;

    // static bool checkSchema(WallVisitor_ptr visitor, SQLExpr x) ;

    // static bool isInTableSource(SQLObject_ptr x) ;

    // static bool isFirstInSubQuery(SQLObject_ptr x) ;

    // static bool isFirstSelectTableSource(SQLObject_ptr x) ;

    // static bool hasTableSource(SQLSelectQuery x) ;

    // static bool hasTableSource(SQLTableSource x) ;

    // static bool isTopStatementWithTableSource(SQLObject_ptr x) ;

    // static bool isTopSelectItem(SQLObject_ptr x) ;

    // static bool isTopSelectStatement(SQLObject_ptr x) ;

    // static bool isTopSelectOutFile(MySqlOutFileExpr x) ;

    // static bool check(WallVisitor_ptr visitor, SQLExprTableSource x) ;

    static void addViolation(WallVisitor_ptr visitor, int errorCode, std::string message, SQLObject_ptr x) ;

    // static void clearViolation(WallVisitor_ptr visitor) ;

    // static bool checkUnion(WallVisitor_ptr visitor, SQLUnionQuery x) ;

    // static bool queryBlockFromIsNull(WallVisitor_ptr visitor, SQLSelectQuery query) ;

    // static bool queryBlockFromIsNull(WallVisitor_ptr visitor, SQLSelectQuery query, bool checkSelectConst);

    // static String form(String name) ;

    // static void loadResource(Set<String> names, String resource) ;

    // static void readFromInputStream(Set<String> names, InputStream in) ;

    // static void preVisitCheck(WallVisitor_ptr visitor, SQLObject_ptr x);

    // static void check(WallVisitor_ptr visitor, SQLCommentHint x) ;

    // static void check(WallVisitor_ptr visitor, SQLJoinTableSource x) ;
};
